<?php
namespace Sdk\Common\Utils;

use Marmot\Core;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

class Email
{
    // 收件人名称
    const RECIPIENT_NAME = 'Customer';
    const EXPIRATION_TIME = 1800;
    const CODE_LENGTH = 5;

    const ACTION = array(
        'MA' => 'MA',// 注册
        'MQ' => 'MQ' // 找回密码
    );
    const LANGUAGE = array(
        'zh' => 'zh', // 中文
        'en' => 'en'  // 英文
    );

    /**
     * @var PHPMailer $mailer
     */
    private $mailer;
    /**
     * @var string $from 发件人邮箱
     */
    private $from;
    /**
     * @var string $name 发件人名称
     */
    private $name;
    /**
     * @var string $recipientAddress 收件人邮箱
     */
    private $recipientAddress;
    /**
     * @var string $recipientName 收件人名称
     */
    private $recipientName;

    public function __construct()
    {
        $this->mailer = null;
        $this->from = Core::$container->get('mail.Username');
        $this->name = Core::$container->get('mail.FromName');
        $this->recipientAddress = '';
        $this->recipientName = self::RECIPIENT_NAME;
    }

    public function __destruct()
    {
        unset($this->mailer);
        unset($this->from);
        unset($this->name);
        unset($this->recipientAddress);
        unset($this->recipientName);
    }

    public function initPHPMailer() : void
    {
        // 实例化PHPMailer
        $mailer = new PHPMailer(true);
        // 邮件调试模式 2
        $mailer->SMTPDebug = 0;
        // 设置邮件使用SMTP
        $mailer->isSMTP();
        // 设置邮件程序以使用SMTP
        $mailer->Host = Core::$container->get('mail.Host');
        // 设置邮件内容的编码
        $mailer->CharSet = 'UTF-8';
        // 启用SMTP验证
        $mailer->SMTPAuth = true;
        // 允许 TLS 或者ssl协议
        $mailer->SMTPSecure = 'ssl';
        // SMTP用户名
        $mailer->Username = Core::$container->get('mail.Username');
        // SMTP密码
        $mailer->Password = Core::$container->get('mail.Password');
        // 使用STARTTLS加密连接
        $mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        // SMTP服务器端口号
        $mailer->Port = Core::$container->get('mail.Port');

        $this->mailer = $mailer;
    }

    public function getMailer() : PHPMailer
    {
        $this->initPHPMailer();
        return $this->mailer;
    }

    public function setFrom(string $from) : void
    {
        $this->from = $from;
    }

    public function getFrom() : string
    {
        return $this->from;
    }

    public function setName(string $name) : void
    {
        $this->name = $name;
    }

    public function getName() : string
    {
        return $this->name;
    }

    public function setRecipientAddress(string $recipientAddress) : void
    {
        $this->recipientAddress = $recipientAddress;
    }

    public function getRecipientAddress() : string
    {
        return $this->recipientAddress;
    }

    public function setRecipientName(string $recipientName) : void
    {
        $this->recipientName = $recipientName;
    }

    public function getRecipientName() : string
    {
        return $this->recipientName;
    }

    public function setExprationTime(int $exprationTime) : void
    {
        $this->exprationTime = $exprationTime;
    }

    public function getExprationTime() : int
    {
        return $this->exprationTime;
    }

    protected function generateCode() : int
    {
        $characters = '0123456789';
        $code = '';
        
        for ($i = 0; $i < self::CODE_LENGTH; $i++) {
            $code .= $characters[rand(0, strlen($characters)-1)];
        }

        if (strlen($code) != self::CODE_LENGTH) {
            $code = $this->generateCode();
        }

        return $code;
    }

    public function send(string $action, string $language) : bool
    {
        $mail = $this->getMailer();
        $code = $this->generateCode();
        
        try {
            //收件人信息
            $mail->setFrom($this->getFrom(), $this->getName());   //发件人邮箱，发件人名称
            $mail->addAddress($this->getRecipientAddress(), $this->getRecipientName());     //收件人邮箱，收件人名称

            //邮件内容
            $mail->isHTML(true);

            list($subject, $body) = $this->getMailContent($action, $language, $code);

            //邮件主题
            $mail->Subject = $subject;//'验证码生成通知';
            //邮件内容
            $mail->Body = $body;//'</br>'.'验证码：<b>'.$code.'</b></br>'.'有效期：<b>'.self::EXPIRATION_TIME.'秒</b>';

            //发送邮件
            $mail->send();
            
            $this->setSession('code', $code);
            // echo 'Message has been sent';   //邮件发送成功
            return true;
        } catch (Exception $e) {
            // echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";  //邮件发送失败
            return false;
        }
    }
    
    /**
     * 设置session
     * @param String $name   session name
     * @param Mixed  $data   session data
     * @param Int    $expire 超时时间(秒)
     */
    public function setSession($name, $data, $expire = self::EXPIRATION_TIME)
    {
        $session_data = array();
        $session_data['data'] = $data;
        $session_data['expire'] = time()+$expire;
        $_SESSION[$name] = $session_data;
    }

    /**
     * 读取session
     * @param  String $name  session name
     * @return Mixed
     */
    public function getSession($name)
    {
        if (isset($_SESSION[$name])) {
            if ($_SESSION[$name]['expire'] > time()) {
                return $_SESSION[$name]['data'];
            } else {
                self::clearSession($name);
            }
        }
        return false;
    }

    /**
     * 清除session
     * @param  String  $name  session name
     */
    private function clearSession($name)
    {
        unset($_SESSION[$name]);
    }

    public function verifyEmailSent() : bool
    {
        if ($this->getSession('PHPSESSID') == $_COOKIE['PHPSESSID']) {
            Core::setLastError(EMAIL_CODE_ALREADY_SENT);
            return false;
        }
        return true;
    }

    protected function getMailContent(string $action, string $language, int $code) : array
    {
        $subject = '';
        $body = '';
        if ($action == self::ACTION['MA']) {
            if ($language == self::LANGUAGE['zh']) {
                $subject = "IDF Platform - 账号注册验证码";
                $body = "<p>尊敬的用户，</p>
                <p>感谢您注册IDF Platform。我们很高兴您加入我们！</p>
                <p>为了完成注册过程，请使用以下验证码来验证您的电子邮件地址：</p>
                <p><b>".$code."</b></p>
                <p>请在注册页面输入此验证码。请注意，验证码在<b>30分钟</b>后将会过期。</p>
                <p>如果您并未尝试在IDF Platform注册账号，请忽略此邮件。</p>
                <p>我们期待着为您提供服务！</p>
                <p>祝您使用愉快，</p>
                <p>IDF Platform团队</p>";
            }
            if ($language == self::LANGUAGE['en']) {
                $subject = "IDF Platform - Account Registration Verification Code";
                $body = "<p>Dear User,</p>
                <p>Thank you for signing up for IDF Platform. We are excited to have you on board!</p>
                <p>To complete your registration process, please use the following verification code to confirm your email address:</p>
                <p><b>".$code."</b></p>
                <p>Enter this code on the registration page. Note that the code will expire in <b>30 minutes</b>.</p>
                <p>If you did not attempt to register an account with IDF Platform, please disregard this email.</p>
                <p>We look forward to serving you!</p>
                <p>Best regards,</p>
                <p>The IDF Platform Team</p>";
            }
        }
        if ($action == self::ACTION['MQ']) {
            if ($language == self::LANGUAGE['zh']) {
                $subject = "IDF Platform - 密码重置验证码";
                $body = "<p>尊敬的用户，</p>
                <p>我们收到了一个请求，要求重置您的IDF Platform账户密码。如果这个请求是由您发起的，请使用以下验证码来继续密码重置流程：</p>
                <p><b>".$code."</b></p>
                <p>请在密码重置页面输入此验证码。请注意，该验证码将在<b>30分钟</b>后过期。</p>
                <p>如果您并未请求重置密码，请忽略此邮件，并考虑更改您的密码以确保账户安全。</p>
                <p>我们始终致力于确保您在IDF Platform的体验既安全又便捷。</p>
                <p>祝您使用愉快，</p>
                <p>IDF Platform团队</p>";
            }
            if ($language == self::LANGUAGE['en']) {
                $subject = "IDF Platform - Password Reset Verification Code";
                $body = "<p>Dear User,</p>
                <p>We have received a request to reset the password for your IDF Platform account. If this was you, please use the following verification code to proceed with resetting your password:</p>
                <p><b>".$code."</b></p>
                <p>Enter this code on the password reset page. Note that the code will expire in <b>30 minutes</b>.</p>
                <p>If you did not request a password reset, please ignore this email, and consider changing your password to ensure your account's security.</p>
                <p>We are here to ensure your experience with IDF Platform is secure and hassle-free.</p>
                <p>Best regards,</p>
                <p>The IDF Platform Team</p>";
            }
        }
        return array($subject, $body);
    }
}
